package com.ys.service.bi.impl;

import com.alibaba.fastjson.JSONObject;
import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.ys.entity.bi.BiClassifyModule;
import com.ys.entity.finance.TcwManageTransact;
import com.ys.enume.bi.BiClassifyModuleEnum;
import com.ys.mapper.bi.BiClassifyModuleMapper;
import com.ys.mapper.bi.BiMapper;
import com.ys.service.bi.BiClassifyModuleService;
import com.ys.util.DateUtil;
import com.ys.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * bi分类模块业务流水分析汇总表
 */
@Service("biClassifyModuleService")
public class BiClassifyModuleServiceImpl implements BiClassifyModuleService {
	private static final Logger logger = LoggerFactory.getLogger(BiClassifyModuleServiceImpl.class);

	@Autowired
	private BiMapper biMapper;

	@Autowired
	private BiClassifyModuleMapper biClassifyModuleMapper;


	//每天定时更新
	@Override
	@Transactional
	public R doCountByDaily()throws Exception {
		//刷取日数据
		updateByDay();

		//刷取月数据
		Date today = new Date();
		String thisMonth =  DateUtil.getYYYY_MM(today);
		String yesterdayMonth =  DateUtil.getYYYY_MM(DateUtil.addDays(today, -1));//昨日月份
		updateByMonth(yesterdayMonth);
		String dayStr = DateUtil.getDD(today);
		if(dayStr.equals("01")) {//如果是月份第一天，刷取当月数据
			updateByMonth(thisMonth);
		}
		return R.ok();
	}

	//每天定时更新汇总表
	@Override
	public R updateByDay()throws Exception {
		Date today = new Date();
		String yesterday =  DateUtil.getYYYY_MM_DD(DateUtil.addDays(today, -1));//昨日日期
		//String beforeYesterday =  DateUtil.getYYYY_MM_DD(DateUtil.addDays(today, -2));//前日日期
		//先删除全部的汇总表信息
		biMapper.delBiClassifyModuleByStatDateType(0);
		getCount(yesterday+" 00:00:00",yesterday+" 23:59:59",yesterday,0,false);
		//getCount(beforeYesterday+" 00:00:00",beforeYesterday+" 23:59:59",yesterday,0,false);
		return R.ok();
	}


	/*
	 * 根据月份刷取
	 */
	@Override
	public R updateByMonth(String month)throws Exception {
		String startTime = month+"-01 00:00:00";

		Date today = new Date();
		String thisMonth =  DateUtil.getYYYY_MM(today);
		//先删除
		biMapper.delBiClassifyModuleByStatDate(month);
		if(month.equals(thisMonth)){//如果是当月
			String dayStr = DateUtil.getDD(today);
			if(dayStr.equals("01")){//如果是月份第一天，月度累计为0
				getCount(startTime,"",month,1,true);
			}else {//如果不是月份第一天
				//结束时间为昨日
				String yesterday =  DateUtil.getYYYY_MM_DD(DateUtil.addDays(today, -1));//昨日日期
				String endTime = yesterday +" 23:59:59";
				getCount(startTime,endTime,month,1,false);
			}
		}else {
			int lastDay = DateUtil.getMonthLastDay(month);//获取月份的最后一天
			String endTime = month+"-"+lastDay+" 23:59:59";
			getCount(startTime,endTime,month,1,false);
		}

		return R.ok();
	}


	/**
	 * 更新汇总表
	 * @param startTime 统计开始时间
	 * @param endTime 统计结束时间
	 * @param statDate 统计日期（yyyy-mm-dd、yyyy-mm）
	 * @param statDateType 统计日期类型（0按日、1按月）
	 * @param isZero 是否直接填入0
	 * @throws Exception
	 */
	public void getCount(String startTime,String endTime,String statDate,int statDateType,boolean isZero)throws Exception {
		logger.info("开始时间："+startTime+"-结束时间："+endTime);
		//获取管理交易类型
		List<TcwManageTransact> typeList = new TcwManageTransact().setStatus(1).queryList();

		//收入
		List<Map<String, Object>> countByIncome = new ArrayList<>();
		//支出
		List<Map<String, Object>> countByOutcome = new ArrayList<>();
		//利润
		List<Map<String, Object>> countByProfit = new ArrayList<>();

		if(!isZero){
			//收入
			countByIncome = biMapper.countBiClassifyModule(startTime, endTime, BiClassifyModuleEnum.DataType.INCOME.value);
			//支出
			countByOutcome = biMapper.countBiClassifyModule(startTime, endTime, BiClassifyModuleEnum.DataType.OUTCOME.value);
			//利润
			countByProfit = biMapper.countBiClassifyModule(startTime, endTime, BiClassifyModuleEnum.DataType.PROFIT.value);
		}
		if(typeList!=null && typeList.size()>0){

			//再遍历新增
			for(TcwManageTransact typeItem:typeList){
				BiClassifyModule entity = new BiClassifyModule();
				String bid = typeItem.getBid();
				entity.setManageTransactBid(bid);//管理分类表bid
				entity.setStatDate(statDate);//统计日期（yyyy-mm-dd、yyyy-mm）
				entity.setStatDateType(statDateType);//统计日期类型（0按日、1按月）
				entity.setClassifyType(BiClassifyModuleEnum.ClassifyType.getValue(typeItem.getFirstType()));//分类类型
				entity.setStatus(1);

				//logger.info("获取管理类型："+bid+"-"+typeItem.getIntegrityType());
				BigDecimal incomeAmount = BigDecimal.ZERO;//收入统计金额
				BigDecimal outcomeAmount = BigDecimal.ZERO;//支出统计金额
				BigDecimal profitAmount = BigDecimal.ZERO;//利润统计金额

				if(!isZero){
					if(countByIncome!=null && countByIncome.size()>0){
						List<Map<String, Object>> countByIncomeByBid = countByIncome.stream().filter(item->item.get("bid").toString().equals(bid)).collect(Collectors.toList());
						if(countByIncomeByBid.size()>0){
							incomeAmount = new BigDecimal(countByIncomeByBid.get(0).get("amount").toString());
						}
					}
					if(countByOutcome!=null && countByOutcome.size()>0){
						List<Map<String, Object>> countByOutcomeByBid = countByOutcome.stream().filter(item->item.get("bid").toString().equals(bid)).collect(Collectors.toList());
						if(countByOutcomeByBid.size()>0){
							outcomeAmount = new BigDecimal(countByOutcomeByBid.get(0).get("amount").toString());
						}
					}
					if(countByProfit!=null && countByProfit.size()>0){
						List<Map<String, Object>> countByProfitByBid = countByProfit.stream().filter(item->item.get("bid").toString().equals(bid)).collect(Collectors.toList());
						if(countByProfitByBid.size()>0){
							profitAmount = new BigDecimal(countByProfitByBid.get(0).get("amount").toString());
						}
					}
				}

				entity.setIncomeAmount(incomeAmount);
				entity.setOutcomeAmount(outcomeAmount.abs());//存绝对值
				entity.setProfitAmount(profitAmount);
				biClassifyModuleMapper.insert(entity);
			}

		}
	}


	//bi页面获取数据，根据类型
	@Override
	public JSONObject getInfoByClassifyType(int classifyType)throws Exception {
		JSONObject res = new JSONObject();

		//******获取头部数据******
		Date today = new Date();
		String yesterday = DateUtil.getYYYY_MM_DD(DateUtil.addDays(today, -1));//昨日日期

		String thisMonth =  DateUtil.getYYYY_MM(today);//当月
		String beforeMonth =  DateUtil.getYYYY_MM(DateUtil.addMonth(today, -1));//上个月
		String lastYearMonth =  DateUtil.getYYYY_MM(DateUtil.addMonth(today, -12));//去年的当月

		String thisYear =  DateUtil.getYYYY(today);//今年
		String beforeYear = lastYearMonth.substring(0, 4);//去年
		BigDecimal yesterdayIncome = BigDecimal.ZERO;//昨日收入
		BigDecimal yesterdayOutcome = BigDecimal.ZERO;//昨日支出
		BigDecimal yesterdayProfit = BigDecimal.ZERO;//昨日利润

		//昨日统计数据
		BiClassifyModule yesterdayInfo = new BiClassifyModule().setStatDate(yesterday).setClassifyType(classifyType).queryFirst();
		if(yesterdayInfo!=null){
			yesterdayIncome = yesterdayInfo.getIncomeAmount();//昨日收入
			yesterdayOutcome = yesterdayInfo.getOutcomeAmount();//昨日支出
			yesterdayProfit = yesterdayInfo.getProfitAmount();//昨日利润
		}

		//当月累计数据
		List<Map<String, Object>> thisMonthTotal = biMapper.getBiClassifyModuleCountByTotal(thisMonth,thisMonth,classifyType);
		//上个月累计数据
		List<Map<String, Object>> beforeMonthTotal = biMapper.getBiClassifyModuleCountByTotal(beforeMonth,beforeMonth,classifyType);
		//去年的当月累计数据
		List<Map<String, Object>> lastYearMonthTotal = biMapper.getBiClassifyModuleCountByTotal(lastYearMonth,lastYearMonth,classifyType);
		//今年累计数据
		List<Map<String, Object>> thisYearTotal = biMapper.getBiClassifyModuleCountByTotal(thisYear+"-01",thisYear+"-12",classifyType);
		//去年累计数据
		List<Map<String, Object>> beforeYearTotal = biMapper.getBiClassifyModuleCountByTotal(beforeYear+"-01",beforeYear+"-12",classifyType);

		Map<String,BigDecimal> countInfoByIncome = countInfo("incomeAmount",thisMonthTotal,beforeMonthTotal,lastYearMonthTotal,thisYearTotal,beforeYearTotal);
		Map<String,BigDecimal> countInfoByOutcome = countInfo("outcomeAmount",thisMonthTotal,beforeMonthTotal,lastYearMonthTotal,thisYearTotal,beforeYearTotal);
		Map<String,BigDecimal> countInfoByProfit = countInfo("profitAmount",thisMonthTotal,beforeMonthTotal,lastYearMonthTotal,thisYearTotal,beforeYearTotal);

		res.put("yesterdayIncome",yesterdayIncome);//昨日收入
		res.put("yesterdayOutcome",yesterdayOutcome);//昨日支出
		res.put("yesterdayProfit",yesterdayProfit);//昨日利润

		//收入
		res.put("monthAccIncome",countInfoByIncome.get("monthAcc"));//月度累计
		res.put("yearAccIncome",countInfoByIncome.get("yearAcc"));//年度累计
		res.put("relativeByMonthIncome",countInfoByIncome.get("relativeByMonth"));//月度环比
		res.put("sameRatioByMonthIncome",countInfoByIncome.get("sameRatioByMonth"));//月度同比
		res.put("relativeByYearIncome",countInfoByIncome.get("relativeByYear"));//年度环比

		//支出
		res.put("monthAccOutcome",countInfoByOutcome.get("monthAcc"));//月度累计
		res.put("yearAccOutcome",countInfoByOutcome.get("yearAcc"));//年度累计
		res.put("relativeByMonthOutcome",countInfoByOutcome.get("relativeByMonth"));//月度环比
		res.put("sameRatioByMonthOutcome",countInfoByOutcome.get("sameRatioByMonth"));//月度同比
		res.put("relativeByYearOutcome",countInfoByOutcome.get("relativeByYear"));//年度环比

		//利润
		res.put("monthAccProfit",countInfoByProfit.get("monthAcc"));//月度累计
		res.put("yearAccProfit",countInfoByProfit.get("yearAcc"));//年度累计
		res.put("relativeByMonthProfit",countInfoByProfit.get("relativeByMonth"));//月度环比
		res.put("sameRatioByMonthProfit",countInfoByProfit.get("sameRatioByMonth"));//月度同比
		res.put("relativeByYearProfit",countInfoByProfit.get("relativeByYear"));//年度环比

		//******获取折线图、表格数据******
		//获取月份信息
		List<String> monthList = DateUtil.getAgoMonth(11);
		String firstMonth = monthList.get(0);//第一个月份
		String lastMonth = monthList.get(monthList.size()-1);//最后一个月份

		//获取统计数据
		List<Map<String, Object>> getCountGroupByMonth = biMapper.getBiClassifyModuleCountGroupByMonth(firstMonth,lastMonth,classifyType);
		List<BigDecimal> totalListByIncome = new ArrayList<>();
		List<BigDecimal> totalListByOutcome = new ArrayList<>();
		List<BigDecimal> totalListByProfit = new ArrayList<>();
		if(getCountGroupByMonth!=null && getCountGroupByMonth.size()>0){
			for(String monthStr : monthList){
				List<Map<String, Object>> getByMonth = getCountGroupByMonth.stream().filter(item->item.get("statDate").toString().equals(monthStr)).collect(Collectors.toList());
				BigDecimal thisIncome = BigDecimal.ZERO;//收入
				BigDecimal thisOutcome = BigDecimal.ZERO;//支出
				BigDecimal thisProfit = BigDecimal.ZERO;//利润
				if(getByMonth.size()>0){
					thisIncome = new BigDecimal(getByMonth.get(0).get("incomeAmount").toString());
					thisOutcome = new BigDecimal(getByMonth.get(0).get("outcomeAmount").toString());
					thisProfit = new BigDecimal(getByMonth.get(0).get("profitAmount").toString());
				}
				totalListByIncome.add(thisIncome);
				totalListByOutcome.add(thisOutcome);
				totalListByProfit.add(thisProfit);
			}
		}

		res.put("monthList",monthList);//月份数据
		res.put("totalListByIncome",totalListByIncome);//收入统计
		res.put("totalListByOutcome",totalListByOutcome);//支出统计
		res.put("totalListByProfit",totalListByProfit);//利润统计

		List<TcwManageTransact> typeList = new TcwManageTransact()
				.setStatus(1)
				.setFirstType(BiClassifyModuleEnum.ClassifyType.getName(classifyType))
				.setOrderby("A.Bid")
				.queryList();

		List<Map<String, Object>> tableListByIn = new ArrayList<>();//收入项目列表
		List<Map<String, Object>> tableListByOut = new ArrayList<>();//支出项目列表


		//收入、支出项目列表
		List<BiClassifyModule> tableList = new BiClassifyModule()
				.setStatDateType(1)
				.setClassifyType(classifyType)
				.where("A.StatDate BETWEEN '"+firstMonth+"' AND '"+lastMonth+"'")
				//.setOrderby("A.StatDate ASC")
				.queryList();

		if(typeList!=null && typeList.size()>0){
			for(TcwManageTransact typeItem : typeList){
				Map<String, Object> inMap = new HashMap<>();
				Map<String, Object> outMap = new HashMap<>();
				inMap.put("integrityType",typeItem.getIntegrityType());
				outMap.put("integrityType",typeItem.getIntegrityType());
				String bid = typeItem.getBid();
				int num= 1;
				for(String monthStr : monthList){
					if(tableList!=null && tableList.size()>0){
						List<BiClassifyModule> tableListByBidMonth = tableList.stream()
								.filter(item->item.getManageTransactBid().equals(bid) && item.getStatDate().equals(monthStr))
								.collect(Collectors.toList());
						if(tableListByBidMonth.size()>0){
							inMap.put("month"+num,tableListByBidMonth.get(0).getIncomeAmount());
							outMap.put("month"+num,tableListByBidMonth.get(0).getOutcomeAmount());
						}else{
							inMap.put("month"+num,0);
							outMap.put("month"+num,0);
						}
					}else{
						inMap.put("month"+num,0);
						outMap.put("month"+num,0);
					}

					num ++;

				}
				tableListByIn.add(inMap);
				tableListByOut.add(outMap);
			}

		}

		res.put("tableList",tableList);//收入、支出项目列表
		res.put("tableListByIn",tableListByIn);//收入项目列表
		res.put("tableListByOut",tableListByOut);//支出项目列表


		return res;
	}



	//同比、环比的获取、计算
	public Map<String,BigDecimal> countInfo(String keyStr,List<Map<String, Object>> thisMonthTotal,List<Map<String, Object>> beforeMonthTotal,
					List<Map<String, Object>> lastYearMonthTotal,List<Map<String, Object>> thisYearTotal,List<Map<String, Object>> beforeYearTotal){
		Map<String,BigDecimal> res = new HashMap<>();
		BigDecimal monthAcc = BigDecimal.ZERO;//月度累计
		BigDecimal yearAcc = BigDecimal.ZERO;//年度累计


		BigDecimal beforeMonthAcc = BigDecimal.ZERO;//上个月-月度累计
		BigDecimal lastYearMonthAcc = BigDecimal.ZERO;//去年当月-月度累计
		BigDecimal beforeYearAcc = BigDecimal.ZERO;//去年-年度累计

		if(thisMonthTotal!=null && thisMonthTotal.size()>0){
			monthAcc = new BigDecimal(thisMonthTotal.get(0).get(keyStr).toString());
		}
		if(beforeMonthTotal!=null && beforeMonthTotal.size()>0){
			beforeMonthAcc = new BigDecimal(beforeMonthTotal.get(0).get(keyStr).toString());
		}
		if(lastYearMonthTotal!=null && lastYearMonthTotal.size()>0){
			lastYearMonthAcc = new BigDecimal(lastYearMonthTotal.get(0).get(keyStr).toString());
		}
		if(thisYearTotal!=null && thisYearTotal.size()>0){
			yearAcc = new BigDecimal(thisYearTotal.get(0).get(keyStr).toString());
		}
		if(beforeYearTotal!=null && beforeYearTotal.size()>0){
			beforeYearAcc = new BigDecimal(beforeYearTotal.get(0).get(keyStr).toString());
		}

		//同比：指今年第n月与去年第n月比；环比：通常是指表示连续2个单位周期（比如连续两月）内的量的变化比
		//同比增长率=（本期数－同期数）÷同期数×100%

		BigDecimal oneHundred = new BigDecimal("100");
		//月度环比
		BigDecimal relativeByMonth = BigDecimal.ZERO;
		if(beforeMonthAcc.compareTo(BigDecimal.ZERO)!=0){
			relativeByMonth = (monthAcc.subtract(beforeMonthAcc)).divide(beforeMonthAcc, 4, RoundingMode.HALF_UP).multiply(oneHundred);
		}
		//月度同比
		BigDecimal sameRatioByMonth = BigDecimal.ZERO;
		if(lastYearMonthAcc.compareTo(BigDecimal.ZERO)!=0){
			sameRatioByMonth = (monthAcc.subtract(lastYearMonthAcc)).divide(lastYearMonthAcc, 4, RoundingMode.HALF_UP).multiply(oneHundred);
		}

		//年度环比
		BigDecimal relativeByYear = BigDecimal.ZERO;
		if(beforeYearAcc.compareTo(BigDecimal.ZERO)!=0){
			relativeByYear = (yearAcc.subtract(beforeYearAcc)).divide(beforeYearAcc, 4, RoundingMode.HALF_UP).multiply(oneHundred);
		}

		res.put("monthAcc",monthAcc);//月度累计
		res.put("yearAcc",yearAcc);//年度累计
		res.put("relativeByMonth",relativeByMonth.setScale(2, RoundingMode.HALF_UP));//月度环比
		res.put("sameRatioByMonth",sameRatioByMonth.setScale(2, RoundingMode.HALF_UP));//月度同比
		res.put("relativeByYear",relativeByYear.setScale(2, RoundingMode.HALF_UP));//年度环比
		return res;
	}



}
